/*
 * @Author: huangwei
 * @Date: 2021-05-17 10:47:59
 * @LastEditors: 黄威
 * @LastEditTime: 2022-02-09 11:39:41
 * @Description: 添加地图服务相关方法和接口
 */
import L from 'leaflet'

import { Component } from 'vue-property-decorator'
import { createService } from '@/utils/service-creator'

import BaseLayerMixin from '../BindMap/BaseLayerMixin'

// todo VISIBLE属性扩展
// L.TileLayer.include({
//     setVisable: function (isVisable) {

//     },
// })

// 修改透明度和可见性方法
function setOpacity(layObj: any, dOpa: number) {
    if (!layObj) return

    // 服务图层
    if (layObj.setOpacity) {
        layObj.setOpacity(dOpa)
    }
    // 矢量图层
    else if (layObj.setStyle) {
        layObj.setStyle({ opacity: dOpa })
    }
    // 图层组
    else if (layObj.eachLayer) {
        layObj.eachLayer((layer: any) => setOpacity(layer, dOpa))
    }
}
function setVisable(layObj: any, isVisable: boolean) {
    if (!layObj) return

    // 获取图层容器
    const getEle: () => HTMLElement = function () {
        if (layObj.getContainer) {
            return layObj.getContainer()
        }
        if (layObj.getElement) {
            return layObj.getElement()
        }
        return
    }

    if (getEle()) {
        getEle().style.visibility = isVisable ? 'visible' : 'hidden'

        if (!isVisable) {
            layObj.createTile = function name() {
                return document.createElement('div')
            }
        } else if (Object.prototype.hasOwnProperty.call(layObj, 'createTile')) {
            delete layObj.createTile
            layObj.redraw()
        }
    }
    // 图层组
    else if (layObj.eachLayer) {
        layObj.eachLayer((layer: any) => setVisable(layer, isVisable))
    }
}

@Component
export default class LayerMixin extends BaseLayerMixin<L.Map, L.Layer> {
    adapter = {
        createLayer(
            svcType: string,
            svcUrl: string,
            props?: any
        ): Promise<L.Layer> {
            return createService(svcType, svcUrl, props)
        },

        addToMap(m: L.Map, l: L.Layer): void {
            m.addLayer(l)
        },
        removeFromMap(m: L.Map, l: L.Layer): void {
            m.removeLayer(l)
        },

        moveLayer(m: L.Map, l: L.TileLayer, l2?: L.TileLayer) {
            if (!l2) l.bringToBack()
            else {
                const z1 = l.options.zIndex
                const z2 = l2.options.zIndex

                // 按照顺序移动dom
                l2.getContainer()!.insertAdjacentElement(
                    'afterend',
                    l.getContainer()!
                )
                // 如果他们层级不一致
                if (z1 !== z2) {
                    l.setZIndex((z2 || 0) + 1)
                }
            }
        },

        setOpacity(l: L.Layer, dOpa: number): void {
            setOpacity(l, dOpa)
        },
        setVisable(l: L.Layer, isVisable: boolean): void {
            setVisable(l, isVisable)
        },
    }
}
